//
//  MyQrCodeTool.swift
//  Intersection
//
//  Created by 好东家 on 2022/8/11.
//

import UIKit

///二维码图片生成工具
public class QrCodeTool: NSObject {
    
    // MARK:  生成二维码
        
    public enum CodeDescriptor: String {
        case qrCpde = "CIQRCodeGenerator"
        //只能识别 ascii characters
        case code128Barcod = "CICode128BarcodeGenerator"
        //显示中文会乱码
        case pdf417 = "CIPDF417BarcodeGenerator"
        //显示中文会乱码
        case aztec = "CIAztecCodeGenerator"
    }

    private enum CodeKey:String{
        ///设置内容
        case inputMessage = "inputMessage"
        ///设置容错级别
        case inputCorrectionLevel = "inputCorrectionLevel"
    }

    ///  容错级别

    /*

     qrCpde 和 pdf417

     inputCorrectionLevel 是一个单字母（@"L", @"M", @"Q", @"H" 中的一个），表示不同级别的容错率，默认为 @"M"

     QR码有容错能力，QR码图形如果有破损，仍然可以被机器读取内容，最高可以到7%~30%面积破损仍可被读取

     相对而言，容错率愈高，QR码图形面积愈大。所以一般折衷使用15%容错能力。错误修正容量 L水平 7%的字码可被修正

     M水平 15%的字码可被修正

     Q水平 25%的字码可被修正

     H水平 30%的字码可被修正

     code128Barcod 不能设置inputCorrectionLevel属性

     aztec inputCorrectionLevel 5 - 95

     */
    public enum  CorrectionLevel{
          case L
          case M
          case Q
          case H
          case aztecLevel(_ value:Int)
          var  levelValue:String{
             switch self {
                case .L:
                    return "L"
                case .M:
                    return "M"
                case .Q:
                    return "Q"
                case .H:
                    return "H"
                default:return  "" }
     }
    }

    /// 生成对应的码图片
        /// - Parameters:
        ///   - string: 图片中的内容
        ///   - descriptor: 码的类型
        ///   - size: 图片的大小
        ///   - color: 图片的颜色
        ///   - level: 码的容错级别
        /// - Returns: 图片
    public func MyToolCreatQRCodeImage(string: String,descriptor: CodeDescriptor,size: CGSize,color:UIColor? = nil,level:CorrectionLevel = .M) -> UIImage? {
        guard let data = string.data(using: .utf8),let filter = CIFilter(name: descriptor.rawValue) else {
            return nil
        }
        

        filter.setValue(data, forKey: CodeKey.inputMessage.rawValue)
        if (descriptor == .qrCpde || descriptor == .pdf417){
            switch level {
            case .L,.M,.Q,.H:
                filter.setValue(level.levelValue, forKey: CodeKey.inputCorrectionLevel.rawValue)
            default:break
            }
        }else if descriptor == .aztec{
            switch level {
            case .aztecLevel(var value):
                if value < 5 {
                    value = 5
                }else if value > 95{
                    value = 95
                }
                filter.setValue(NSNumber.init(value: value), forKey: CodeKey.inputCorrectionLevel.rawValue)
            default:break
            }
        }
        
        guard let image = filter.outputImage else {
            return nil
        }
        
        let imageSize = image.extent.size
        let transform = CGAffineTransform(scaleX: size.width / imageSize.width,y: size.height / imageSize.height)
        let scaledImage = image.transformed(by: transform)
        
        guard let codeColor = color else{
            return UIImage.init(ciImage: scaledImage)
        }
        
        // 设置颜色
        let colorFilter = CIFilter(name: "CIFalseColor", parameters: ["inputImage":scaledImage,"inputColor0":CIColor(cgColor: codeColor.cgColor ),"inputColor1":CIColor(cgColor: UIColor.clear.cgColor)])
        
        guard let newOutPutImage = colorFilter?.outputImage else {
            return UIImage.init(ciImage: scaledImage)
        }
        
        return UIImage.init(ciImage: newOutPutImage)
    }


    /// 叠加图片
    /// - Parameters:
    ///   - inputImage: 码图片/背景
    ///   - fillImage: 中间的icon图片
    ///   - fillSize: icon的大小
    /// - Returns: 合成后的图片
    public func MyToolSuperpositionfillImage(_ inputImage:UIImage?,_ fillImage:UIImage?,_ fillSize:CGSize) -> UIImage? {
       guard let input = inputImage,let fill = fillImage  else {
           return inputImage
       }
       let imageSize = input.size
       UIGraphicsBeginImageContext(imageSize)
       input.draw(in: CGRect.init(x: 0, y: 0, width: imageSize.width, height: imageSize.height))
       let fillWidth = min(imageSize.width, fillSize.width)
       let fillHeight = min(imageSize.height, fillSize.height)
       let fillRect = CGRect(x: (imageSize.width - fillWidth)/2, y: (imageSize.height - fillHeight)/2, width: fillWidth ,height: fillHeight)
       fill.draw(in: fillRect)
       guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else {
           UIGraphicsEndImageContext()
           return inputImage
       }
       UIGraphicsEndImageContext()
       return newImage
    }

}
